vimfandomcom-20200223-history
Restore screen size and position
This tip is useful if you always want Vim to startup in the same location and size as the time you exit it. Most applications (i.e. FireFox) do this already. Another reason to use this tip is if you often have more than one Vim (GUI on Windows) running. Quite often I will have one per project, each instance editing multiple buffers. When I start Vim, I name it (based on the project or tool I launched it from). gvim myFile1 myFile2 gvim --servername MyProject filename1 filename2 filename3 gvim --servername VS_NET filename When I re-open Vim I like its screen position and size to be the same as they were when Vim was closed. The scripts below can be added to your .vimrc file. They offer 2 configuration options which can be set at the bottom before the autocmds: " To enable the saving and restoring of screen positions. let g:screen_size_restore_pos = 1 " To save and restore screen for each Vim instance. " This is useful if you routinely run more than one Vim instance. " For all Vim to use the same settings, change this to 0. let g:screen_size_by_vim_instance = 1 Version 1 (Vim 7 and above) This version uses Vim's readfile() and writefile() functions to access the file used to save the size/position. That in addition to the use of the split() function makes this version unusable in Vim 6.x. if has("gui_running") function! ScreenFilename() if has('amiga') return "s:.vimsize" elseif has('win32') return $HOME.'\_vimsize' else return $HOME.'/.vimsize' endif endfunction function! ScreenRestore() " Restore window size (columns and lines) and position " from values stored in vimsize file. " Must set font first so columns and lines are based on font size. let f = ScreenFilename() if has("gui_running") && g:screen_size_restore_pos && filereadable(f) let vim_instance = (g:screen_size_by_vim_instance 1?(v:servername):'GVIM') for line in readfile(f) let sizepos = split(line) if len(sizepos) 5 && sizepos0 vim_instance silent! execute "set columns=".sizepos1." lines=".sizepos2 silent! execute "winpos ".sizepos3." ".sizepos4 return endif endfor endif endfunction function! ScreenSave() " Save window size and position. if has("gui_running") && g:screen_size_restore_pos let vim_instance = (g:screen_size_by_vim_instance 1?(v:servername):'GVIM') let data = vim_instance . ' ' . &columns . ' ' . &lines . ' ' . \ (getwinposx()<0?0:getwinposx()) . ' ' . \ (getwinposy()<0?0:getwinposy()) let f = ScreenFilename() if filereadable(f) let lines = readfile(f) call filter(lines, "v:val !~ '^" . vim_instance . "\\>'") call add(lines, data) else let lines = data endif call writefile(lines, f) endif endfunction if !exists('g:screen_size_restore_pos') let g:screen_size_restore_pos = 1 endif if !exists('g:screen_size_by_vim_instance') let g:screen_size_by_vim_instance = 1 endif autocmd VimEnter * if g:screen_size_restore_pos 1 | call ScreenRestore() | endif autocmd VimLeavePre * if g:screen_size_restore_pos 1 | call ScreenSave() | endif endif Version 2 (Vim 6 and above) Here is an alternative script which uses a regular Vim buffer to manipulate the vimsize file instead of Vim 7's readfile() and writefile() functions. " Restore screen size and position " Saves data in a separate file, and so works with multiple instances of Vim. if has("gui_running") function! ScreenFilename() if has('amiga') return "s:.vimsize" elseif has('win32') return $HOME.'\_vimsize' else return $HOME.'/.vimsize' endif endfunction function! ScreenRestore() " - Remembers and restores winposition, columns and lines stored in " a .vimsize file " - Must follow font settings so that columns and lines are accurate " based on font size. if !has("gui_running") return endif if g:screen_size_restore_pos != 1 return endif let vim_instance = (g:screen_size_by_vim_instance 1?(v:servername):'GVIM') " read any existing variables from .vimsize file silent! execute "sview " . escape(ScreenFilename(),'%#\ $') silent! execute "0/^" . vim_instance . " /" let vim_name = matchstr(getline('.'), '^\w\+') let vim_cols = matchstr(getline('.'), '^\w\+\s\+\zs\d\+') let vim_lines = matchstr(getline('.'), '^\w\+\s\+\d\+\s\+\zs\d\+') let vim_posx = matchstr(getline('.'), '^\w\+\s\+\d\+\s\+\d\+\s\+\zs\d\+') let vim_posy = matchstr(getline('.'), '^\w\+\s\+\d\+\s\+\d\+\s\+\d\+\s\+\zs\d\+') if vim_name vim_instance execute "set columns=".vim_cols execute "set lines=".vim_lines silent! execute "winpos ".vim_posx." ".vim_posy endif silent! q endfunction function! ScreenSave() " used on exit to retain window position and size if !has("gui_running") return endif if !g:screen_size_restore_pos return endif let vim_instance = (g:screen_size_by_vim_instance 1?(v:servername):'GVIM') silent! execute "split " . escape(ScreenFilename(),'%#\ $') silent! execute "0/^" . vim_instance . " /" let vim_name = matchstr(getline('.'), '^\w\+') if vim_name vim_instance delete _ endif $put = vim_instance . ' ' . &columns . ' ' . &lines . ' ' . \ (getwinposx()<0?0:getwinposx()) . ' ' . \ (getwinposy()<0?0:getwinposy()) silent! x! endfunction if !exists('g:screen_size_restore_pos') let g:screen_size_restore_pos = 1 endif if !exists('g:screen_size_by_vim_instance') let g:screen_size_by_vim_instance = 1 endif autocmd VimEnter * call ScreenRestore() autocmd VimLeavePre * call ScreenSave() endif Comments Feel free to add comments here for script improvements. For the Version 2 script, since it uses Vim buffers for the manipulations it would be useful to disable all autocmds before opening splitting the buffer and re-enable them when closing the buffer. Many people have lots of plugins installed which can make opening buffers somewhat expensive (and therefore unnecessary time delay). Using the Vim 7 readfile() and writefile() functions avoid this overhead.